home *** CD-ROM | disk | FTP | other *** search
- /*
- * Lar - LU format library file maintainer
- * by Stephen C. Hemminger
- * Bedford MA
- *
- * DeSmet version T. Bonfield Feb 84
- * DeSmet updates R. McVay Mar 84
- */
- #define VERSION 2
- #define REVISION 61
- #define LAST_MOD "27 Oct 84"
- /*
- * DESCRIPTION
- * Lar is a program to manipulate CP/M LU format libraries.
- * The original CP/M library program LU is the product
- * of Gary P. Novosielski. The primary use of lar is to combine several
- * files together for upload/download to a personal computer.
- *
- * Usage: lar [-]key library [files] ...
- *
- * Key functions are:
- * a - Add files to library (also creates new libraries)
- * l - List directory of library
- * e - Extract files from library
- * p - Print files in library
- * d - Delete files in library
- * r - Reorganize library
- *
- * EXAMPLES:
- * lar l foo.lbr list all files in FOO.LBR
- * lar e foo.lbr 1.c 2.c extract files 1.c, 2.c from FOO.LBR
- * lar p foo.lbr 1.c display 1.c from FOO.LBR
- * lar a foo.lbr 1.c 2.c 3.c add or replace files in FOO.LBR
- *
- * When creating a new library, you will be prompted for the maximum
- * number of entries it can contain. Assuming NEW.LBR doen't exist ...
- * lar a new.lbr create an empty library
- * lar a new.lbr a.c,b.c,d.c create NEW.LBR, add files.
- *
- * The Reorganize option causes <lbrfile>.tmp to be created, and
- * the contents of the old library to be copied into it.
- *
- * This program is public domain software, no warranty intended or
- * implied.
- *
- *
- * PORTABILITY
- * The original version by Stephan C. Hemminger was set up for
- * Version 7 UNIX, and was not useable as is. It has been hacked
- * to fit the DeSmet C compiler for MSDOS. The basic
- * problems were: fread() and fwrite() incompatibility, no
- * text/binary differentiation problem in MSDOS.
- *
- * Also, I have made random changes to the source merely to reflect
- * my programming taste; he original code was quite good. I have also
- * changed the wording of some errors, etc more in line with the current
- * flavor of messages in the micro environment. The original Verbose
- * flag option was removed, and made the default. No need to suppress
- * what few messages and text there is.
- *
- * As mentioned before, ther is no problem with text or binary files;
- * they are treated identically. Control-Z characters are added to the
- * end of all files to round it up to a multiple of 128 bytes.
- *
- * Note that all files are kept as multiples of 128 bytes, to be
- * compatible with the CP/M utility LU. This may present a problem
- * with certain data files, but will be OK for text and .COM files
- * anyways, and probably most other files.
- * T. Bonfield
- *
- * v1.1- added the exception handler for a "dashed" option and a default
- * library extension of .lbr.
- * - fixed a bug that put the drive descriptor into the library file
- * entry.
- * v1.2- fixed a "member not found" bug by forcing all filenames to lower
- * case.
- * - changed the commands u->a and t->l to jive with LU better.
- * v1.3- fixed subtle "casting" bug in copyentry().
- * - copyentry() now uses acopy().
- * - rewrote fcopy() and acopy() to use 16K copy buffer to
- * eliminate disk thrashing on -a -e & -r.
- * - fixed "not enough room" bug in reorg().
- * v1.4- fixed bug in acopy() that crashed big member extractions.
- * - increased copy buffer size to 32K - 128.
- * v2.0-2.2- wildcards added by P.H. Mack based on v1.1
- * v2.3-2.4- ???
- * v2.5- wildcard references to members added to v1.4 (inspired by P.H. Mack)
- * - cleaned up acopy()'s handling of -p option
- * - generalized getname() & cvt_to_fcb a little
- * v2.6- wildcards for -a
- * v2.61-cleaned up a bit, sprinked in a few console status checks for
- * MultiLink users
- * R. McVay
- *
- * * Unix is a trademark of Bell Labs.
- * ** CP/M is a trademark of Digital Research.
- */
-
-
- #include <stdio.h>
-
- /* Library file status values: */
-
- #define ACTIVE 0
- #define UNUSED 0xff
- #define DELETED 0xfe
- #define CTRLZ 0x1a
-
- #define MAXFILES 256
- #define SECTOR 128
- #define BIGBUFF 32640
- #define DSIZE (sizeof(struct ludir))
- #define SLOTS_SEC (SECTOR/DSIZE)
- #define equal(s1, s2) ( strcmp(s1,s2) == 0 )
- #define FALSE 0
- #define TRUE 1
- #define BOOL int
-
- /* Globals */
- char *fname[MAXFILES];
- BOOL ftouched[MAXFILES];
-
- struct ludir { /* internal dir. stucture, 32 bytes */
- char l_stat; /* 12 byte filename: */
- char l_name[8];
- char l_ext[3];
- int l_off; /* offset in library, */
- int l_len; /* length of file, */
- char l_fill[16]; /* 16 byte filler, */
- } ldir[MAXFILES];
-
- int errcnt,
- nfiles,
- nslots;
-
- char *getname(),
- *strlower(),
- *malloc();
-
- long lseek();
-
- char aname[20]; /* global library name reference */
-
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- char *flagp,
- *request;
-
- if (argc < 3)
- help();
- if (*argv[1] == '-') /* strip the dash if present */
- ++argv[1];
- *argv[1] = tolower(*argv[1]);
-
- strcpy(aname, argv[2]); /* name of LBR file, */
- if ((index(aname, "*") > -1) || (index(aname, "?") > -1))
- error("wildcards not allowed in library name");
- if (index(aname, ".") == -1) /* add default extension .lbr */
- strcat(aname, ".lbr");
- argv[2] = aname;
-
- filenames(argc, argv);
-
- switch (*argv[1])
- {
- case 'l': /* list table of contents */
- table(aname);
- break;
-
- case 'a': /* add */
- update(aname);
- break;
-
- case 'e': /* extract members */
- getfiles(aname, FALSE);
- break;
-
- case 'p': /* print members */
- getfiles(aname, TRUE);
- break;
-
- case 'd': /* delete members */
- delete(aname);
- break;
-
- case 'r': /* reorganize library */
- reorg(aname);
- break;
-
- default: /* bad request */
- printf("err: unrecognized function [%s]\n\n", argv[1]);
- help();
- break;
- }
- exit(0);
- }
-
-
- /************************************************************************
- * Get file names, check for dups, and initialize *
- * This is where we'll encounter and expand wildcards *
- ************************************************************************/
-
- filenames(ac, av)
- int ac;
- char *av[];
- {
- int i,
- j;
-
- errcnt = 0;
- for (i = 3, j = 0; i < ac; i++, j++)
- {
- fname[j] = calloc(15, 1); /* we're going to copy all file args */
- cvt_to_fcb(strlower(av[i]), fname[j]);
- ftouched[j] = FALSE;
- if (j >= MAXFILES)
- error("Too many file names."); /* we'll double check in wildexp() */
- if (index(fname[j], "?") > -1)
- j = wildexp(j, *av[1]);
- }
- nfiles = j;
-
- for (i = 0; i < nfiles; i++) /* pack 'em back up */
- {
- j = index(fname[i], ":") + 1;
- strcpy(fname[i]+j, getname(fname[i]+j));
- }
-
- for (i = 0; i < nfiles; i++)
- {
- for (j = i + 1; j < nfiles; j++)
- {
- if (equal(fname[i], fname[j]))
- {
- printf("%s ", fname[i]);
- error("duplicate file name");
- }
- }
- }
- }
-
-
- /************************************************************************
- * Do wildcard expansion of ambiguous name at fname[j]. *
- * Return the resulting "expanded" index to the last name in the fname *
- * list. *
- ************************************************************************/
-
- wildexp(j, func)
- int j;
- char func;
- {
- #define GETDTA 0x2F00
- #define FIRST 0x1100
- #define NEXT 0x1200
- FILE lfd;
- char pattern[15], libname[15];
- int i, k, mode, oj;
- int our_dta_oset, our_dta_seg;
- extern int _rax, _rbx, _rdx, _rds, _res;
-
- struct fcb
- {
- char drvnum,
- name[8],
- ext[3],
- misc[20];
- } search_fcb;
-
-
- strcpy(pattern, fname[j]); /* this allows us to return an */
- free(fname[j]); /* index to a valid name, even */
- oj = --j; /* if none is found here */
-
- if (func == 'a')
- {
- /* Then expansion must be done on disk file names. *
- * Sorry, but this is very compiler dependent. The *
- * following code uses DeSmet's _doint() and a pre- *
- * defined set of "register" variables. */
-
- for (i = 0; i < 15; libname[i++] = '\0')
- ;
- cvt_to_fcb(aname, libname);
-
- _rax = GETDTA;
- _doint(0x21);
- our_dta_seg = _res;
- our_dta_oset = _rbx;
-
- /* The first order of business is to set up the fcb *
- * the DOS will use as a pattern for the search. */
-
- if (pattern[1] == ':') /* set up drive number */
- {
- search_fcb.drvnum = toupper(*pattern) - 'A' + 1;
- strcpy(search_fcb.name, pattern + 2);
- }
- else
- {
- search_fcb.drvnum = '\0';
- strcpy(search_fcb.name, pattern);
- }
-
- /* Now we'll scan any matching filenames into *
- * fnames[] using an algorithm stolen shamelessly *
- * from sq18u.c. */
-
- for (mode = FIRST;; mode = NEXT)
- {
- csts(); /* for MultiLink users */
- _rdx = search_fcb;
- _rds = -1;
- _rax = mode;
- _doint(0x21);
- if ((_rax & 0xFF) == 0xFF) /* no match found */
- break;
-
- ++j;
- if (j >= MAXFILES)
- error("(wildexp) too many files");
- else
- fname[j] = calloc(15, 1);
- if (!fname[j])
- error("(wildexp) out of memory");
- else
- {
- if (pattern[1] == ':')
- {
- fname[j][0] = *pattern;
- fname[j][1] = ':';
- i = 2;
- }
- else
- i = 0;
- _lmove(11, our_dta_oset + 1, our_dta_seg, &fname[j][i], _showds());
- fname[j][i + 11] = '\0';
- if (equal(libname, fname[j]))
- {
- free(fname[j]);
- --j;
- }
- }
- }
- }
- else
- {
- /* expansion is from names in library table of contents */
- /* library name can't be ambiguous */
- if ((lfd = open(aname, 2)) == -1)
- cant(aname);
- getdir(lfd);
-
- for (i = 1; i < nslots; i++)
- {
- csts(); /* for MultiLink users */
- if (ldir[i].l_stat == ACTIVE)
- {
- ldir[i].l_off = 0; /* setting up end of string */
- if (amatch(pattern, ldir[i].l_name))
- {
- ++j;
- if (j >= MAXFILES)
- error("(wildexp) too many files");
- else
- fname[j] = calloc(15, 1);
- if (!fname[j])
- error("(wildexp) out of memory");
- else
- strcpy(fname[j], ldir[i].l_name);
- }
- }
- }
- }
- if (j == oj)
- printf("wildexp: %s not matched\n", pattern);
- return(j);
- }
-
-
- /************************************************************************
- * try to match a filename to an ambiguous pattern; lengths must match *
- ************************************************************************/
-
- amatch(pattern, fname)
- char *pattern,
- *fname;
- {
- while (*pattern && *fname)
- {
- if ((*pattern != '?') && (*pattern != *fname))
- return(FALSE);
- ++pattern;
- ++fname;
- }
- return(*pattern == *fname);
- }
-
-
- /************************************************************************
- * list the contents and statistics of the library *
- ************************************************************************/
-
- table(lib)
- char *lib;
- {
- FILE lfd;
- int i,
- total;
- int active = 0,
- unused = 0,
- deleted = 0;
- char *uname;
-
- if ((lfd = open(lib,2)) == -1)
- cant(lib);
-
- getdir(lfd);
- total = ldir[0].l_len;
- printf("Name Index Length (128 byte blocks)\n");
- printf("Directory %4u %6u\n", 0, total);
-
- for (i = 1; i < nslots; i++)
- {
- csts(); /* for MultiLink users */
- switch(ldir[i].l_stat)
- {
- case ACTIVE:
- active++;
- uname = getname(&ldir[i].l_name);
- total += ldir[i].l_len;
- printf("%-12s %4u %7u\n", uname,ldir[i].l_off,ldir[i].l_len);
- break;
- case UNUSED:
- unused++;
- break;
- default:
- deleted++;
- break;
- }
- }
- printf("-----------------------------\n");
- printf("Total blocks %7u\n", total);
- printf("\nLibrary %s has %u slots, %u deleted, %u active, %u unused\n",
- lib, nslots, deleted, active, unused);
- close(lfd);
- not_found ();
- }
-
-
- /************************************************************************
- * add new members to a library; create the library if necessary *
- ************************************************************************/
-
- update(name)
- char *name;
- {
- FILE lfd;
- int i;
-
- if ((lfd = open(name,2)) == -1)
- {
- if ((lfd = creat(name)) == -1)
- cant(name);
- initdir(lfd);
- }
- getdir(lfd); /* read directory, */
-
- for (i = 0; (i < nfiles) && (errcnt == 0); i++)
- addfil(fname[i], lfd);
- if (errcnt != 0)
- printf("fatal errors - last file may be bad\n");
- putdir(lfd);
- close(lfd);
- }
-
-
- /************************************************************************
- * extract (or print if pflag) a library member *
- ************************************************************************/
-
- getfiles(name, pflag)
- char *name;
- BOOL pflag;
- {
- FILE lfd,
- ofd;
- int i;
- char *unixname;
-
- if ((lfd = open(name,2)) == -1)
- cant (name);
-
- getdir(lfd);
-
- for (i = 1; i < nslots; i++)
- {
- if (ldir[i].l_stat == ACTIVE)
- {
- unixname = getname(&ldir[i].l_name);
- if (filarg(unixname))
- {
- printf("Extracting %s\n", unixname);
-
- if (pflag)
- ofd = STDOUT;
- else
- ofd = creat(unixname);
-
- if (ofd == -1)
- {
- printf("%s - can't create output file\n",unixname);
- errcnt++;
- }
- else
- {
- lseek(lfd, (long) ldir[i].l_off * SECTOR,0);
- acopy(lfd, ofd, ldir[i].l_len);
- if (!pflag)
- close(ofd);
- }
- }
- }
- }
- close(lfd);
- not_found();
- }
-
-
- /************************************************************************
- * mark a library directory entry as deleted *
- ************************************************************************/
-
- delete(lname)
- char *lname;
- {
- FILE f;
- int i;
-
- if ((f = open(lname,2)) == -1)
- cant(lname);
-
- if (nfiles <= 0)
- error("delete by name only");
-
- getdir(f);
- for (i = 0; i < nslots; i++)
- {
- if (filarg(getname(&ldir[i].l_name)))
- ldir[i].l_stat = DELETED;
- }
-
- not_found();
- if (errcnt > 0)
- printf("errors - library not updated\n");
- else
- putdir(f);
- close(f);
- }
-
-
- /************************************************************************
- * reorganize a library *
- ************************************************************************/
-
- reorg(name)
- char *name;
- {
- FILE olib,
- nlib;
- int oldsize,
- i,
- j;
- struct ludir odir[MAXFILES];
- char tmpname[SECTOR];
-
- for (i = 0; (i < 8) && (name[i] != '.'); i++) /* copy filename, */
- tmpname[i]= name[i]; /* strip off extention, */
- tmpname[i]= '\0';
- strcat(tmpname,".tmp"); /* make new name, */
-
- if ((olib = open(name,2)) == -1)
- cant(name);
-
- if ((nlib = creat(tmpname)) == -1)
- cant(tmpname);
-
- getdir(olib);
- printf("Old library has %d slots\n", oldsize = nslots);
- for (i = 0; i < nslots ; i++)
- copymem((char *)&odir[i], (char *)&ldir[i], sizeof(struct ludir));
- initdir(nlib);
- errcnt = 0;
-
- for (i = j = 1; (i < oldsize) && !errcnt; i++)
- {
- if (odir[i].l_stat == ACTIVE)
- {
- printf("Copying: %-8.8s.%3.3s\n", &odir[i].l_name, &odir[i].l_ext);
- copyentry(&odir[i], olib, &ldir[j], nlib);
- if (++j > nslots)
- {
- errcnt++;
- printf("Not enough room in new library\n");
- }
- }
- }
-
- close(olib);
- putdir(nlib);
- close(nlib);
-
- if (errcnt)
- {
- printf("Errors, library not updated\n");
- unlink(tmpname);
- }
- else
- {
- unlink(name); /* delete orig file, */
- rename(tmpname,name); /* rename it, */
- }
- }
-
-
- /************************************************************************
- * print error message and exit *
- ************************************************************************/
-
- help()
- {
- printf("LAR v%d.%d - %s\n", VERSION, REVISION, LAST_MOD);
- printf("\nUsage: lar [-]<aledrp> library [files] ...\n");
- printf("\nFunctions are:\n\ta - Add files to library (*)\n");
- printf("\tl - List library directory\n");
- printf("\te - Extract files from library (*)\n");
- printf("\td - Delete files in library (*)\n");
- printf("\tr - Reorganize library\n");
- printf("\tp - Print files in library (*)\n");
- printf("\nAssumed library extension is .LBR\n");
- printf("\n(*) Wildcards allowed with these functions.\n");
- exit(1);
- }
-
-
- /************************************************************************
- * return index of t in s, -1 if none *
- ************************************************************************/
-
- index(s, t)
- char *s,
- *t;
- {
- int i,
- j,
- k;
-
- for (i = 0; s[i] != '\0'; i++)
- {
- for (j = i, k = 0; t[k] != '\0' && s[j] == t[k]; j++, k++)
- ;
- if (t[k] == '\0')
- return(i);
- }
- return(-1);
- }
-
-
- /************************************************************************
- * print an error message string and exit *
- ************************************************************************/
-
- error(str)
- char *str;
- {
- printf("LAR: %s\n", str);
- exit(1);
- }
-
-
- /************************************************************************
- * can't perform function because of file error *
- ************************************************************************/
-
- cant(name)
- char *name;
- {
-
- printf("%s: File open error\n", name);
- exit(1);
- }
-
-
- /************************************************************************
- * read the directory of a library into the ludir structure *
- ************************************************************************/
-
- getdir(f)
- FILE f;
- {
- int cnt;
-
- lseek(f,0L,0);
- if (read(f,&ldir[0],DSIZE) != DSIZE) /* read 1st entry to find */
- error("No directory\n"); /* number of slots, */
-
- nslots = ldir[0].l_len * SLOTS_SEC;
- cnt = DSIZE * (nslots - 1); /* already read one slot, */
-
- if (read(f,&ldir[1],cnt) != cnt)
- error("Can't read directory - is it a library?");
- }
-
-
- /************************************************************************
- * write the ludir structure to the beginning of the library file *
- ************************************************************************/
-
- putdir(f)
- FILE f;
- {
-
- lseek(f,0L,0);
- if (write(f,&ldir,nslots * DSIZE) != (nslots * DSIZE))
- error("Can't write directory - library may be botched");
- }
-
-
- /************************************************************************
- * format a virgin library directory *
- ************************************************************************/
-
- initdir(f)
- FILE f;
- {
- int i;
- int numsecs;
- char line[80];
-
- do
- {
- puts ("Number of slots to allocate: ");
- gets(line);
- putchar('\n');
- nslots = atoi (line);
- if (nslots < 1)
- {
- nslots = 0;
- printf("Must have at least one!\n");
- }
- else if (nslots > MAXFILES)
- {
- nslots = 0;
- printf("Too many slots\n");
- }
- }
- while (nslots == 0);
-
- numsecs = nslots / SLOTS_SEC;
- if (nslots != numsecs * SLOTS_SEC)
- ++numsecs;
- nslots = numsecs * SLOTS_SEC;
-
- for (i = 0; i < nslots; i++)
- {
- ldir[i].l_stat = UNUSED;
- blank_fill(&ldir[i].l_name,8);
- blank_fill(&ldir[i].l_ext,3);
- }
- ldir[0].l_stat = ACTIVE;
- ldir[0].l_len = numsecs;
-
- putdir(f);
- }
-
-
- /************************************************************************
- * Fill a string with blanks, no trailing null *
- ************************************************************************/
-
- blank_fill(s, n)
- char *s;
- int n;
- {
- while (n--) *s++= ' ';
- }
-
-
- /************************************************************************
- * convert nm.ex to a Unix style string *
- ************************************************************************/
-
- char *getname(nm)
- char *nm;
- {
- static char namebuf[14];
- int i,
- j;
-
- for (i = 0; (i < 8) && (nm[i] != ' '); i++)
- namebuf[i] = tolower(nm[i]);
- namebuf[i++] = '.';
- j = i;
-
- for (i = 8; (i < 11) && (nm[i] != ' '); i++, j++)
- namebuf[j] = tolower(nm[i]);
- namebuf[j] = '\0';
-
- return namebuf;
- }
-
-
- /************************************************************************
- * check if name matches argument list *
- ************************************************************************/
-
- filarg(name)
- char *name;
- {
- register int i;
-
- if (nfiles <= 0)
- return 1;
-
- for (i = 0; i < nfiles; i++)
- if (equal(name, fname[i]))
- {
- ftouched[i] = TRUE;
- return 1;
- }
-
- return 0;
- }
-
-
- /************************************************************************
- * tolower() all characters in a string *
- ************************************************************************/
-
- char *strlower(string)
- char *string;
- {
- char *ptr;
-
- ptr = string;
- while (*string)
- {
- *string = tolower(*string);
- ++string;
- }
- return(ptr);
- }
-
-
- /************************************************************************
- * print an error message for unmatched argument and bump errcnt *
- ************************************************************************/
-
- not_found()
- {
- register int i;
-
- for (i = 0; i < nfiles; i++)
- if (!ftouched[i])
- {
- printf("%s : not in library.\n", fname[i]);
- errcnt++;
- }
- }
-
-
- /************************************************************************
- * copy nsec*128 bytes from one file to another *
- ************************************************************************/
-
- acopy(fdi, fdo, nsecs)
- FILE fdi,
- fdo;
- int nsecs;
- {
- char *buf;
- int n,
- i;
-
- if ((buf = malloc(BIGBUFF)) == 0)
- error("acopy: not enough memory for BIGBUFF");
-
- do
- {
- csts(); /* for MultiLink users */
- if ((n = read(fdi, buf, min(BIGBUFF/SECTOR, nsecs) * SECTOR)) == -1)
- error("acopy: read error");
- if (fdo == STDOUT)
- {
- for (i = 0; (i < n) && (buf[i] != CTRLZ); i++)
- putchar(buf[i]);
- if (buf[i] == CTRLZ)
- puts("\n\n");
- }
- else if (write(fdo, buf, n) != n)
- error("acopy: write error");
- nsecs -= n/SECTOR;
- }
- while (nsecs);
-
- free(buf);
- }
-
-
- /************************************************************************
- * return the lesser of two numbers *
- ************************************************************************/
-
- min(num1, num2)
- int num1,
- num2;
- {
- if (num1 < num2)
- return(num1);
- else
- return(num2);
- }
-
-
- /************************************************************************
- * add a member to the library *
- ************************************************************************/
-
- addfil(name, lfd)
- char *name;
- FILE lfd;
- {
- FILE ifd;
- int secoffs,
- numsecs,
- i;
-
- if ((ifd = open(name,2)) == -1)
- {
- printf("--- can't find library %s\n",name);
- errcnt++;
- return;
- }
- for (i = 0; i < nslots; i++)
- {
- if (equal(getname(&ldir[i].l_name), name))
- {
- printf("Updating existing file %s\n", name);
- break;
- }
- if (ldir[i].l_stat != ACTIVE)
- {
- printf("Adding new file %s\n", name);
- break;
- }
- }
- if (i >= nslots)
- {
- printf("Can't add %s, library is full\n", name);
- errcnt++;
- return;
- }
-
- ldir[i].l_stat = ACTIVE;
- name += index(name, ":") + 1; /* remove drive descriptor */
- cvt_to_fcb(name, &ldir[i].l_name);
- /* append to end */
- secoffs = lseek(lfd, 0L, 2) / SECTOR;
-
- ldir[i].l_off = secoffs;
- numsecs = fcopy(ifd, lfd);
- ldir[i].l_len = numsecs;
- close(ifd);
- }
-
-
- /************************************************************************
- * copy a complete file into the library *
- ************************************************************************/
-
- fcopy(ifd, ofd)
- FILE ifd,
- ofd;
- {
- int total = 0;
- int n;
- char *sectorbuf;
-
- if ((sectorbuf = malloc(BIGBUFF)) == 0)
- error("fcopy: no buffer");
-
- do
- {
- csts(); /* for MultiLink users */
- if ((n = read(ifd, sectorbuf, BIGBUFF)) == -1)
- error("fcopy: read error");
- while (n % SECTOR)
- sectorbuf[n++] = CTRLZ;
- if (write(ofd, sectorbuf, n) != n)
- error("fcopy: write error");
- total += n/SECTOR;
- }
- while (n == BIGBUFF);
-
- free(sectorbuf);
- return total;
- }
-
-
- /************************************************************************
- * copy a directory entry from one ludir structure to another *
- ************************************************************************/
-
- copyentry(old, of, new, nf)
- struct ludir *old,
- *new;
- FILE of,
- nf;
- {
- int secoffs,
- numsecs;
-
- new->l_stat = ACTIVE;
- copymem(&new->l_name, &old->l_name, 8);
- copymem(&new->l_ext, &old->l_ext, 3);
- lseek(of, (long)old->l_off * SECTOR, 0); /* home of subtle bug */
- secoffs = lseek(nf, 0L, 2) / SECTOR;
-
- new->l_off = secoffs;
- numsecs = old->l_len;
- new->l_len = numsecs;
-
- acopy(of, nf, numsecs);
- }
-
-
- /************************************************************************
- * memory move used by copyentry() *
- ************************************************************************/
-
- copymem(dst, src, n)
- char *dst,
- *src;
- unsigned n;
- {
- while(n--)
- *dst++ = *src++;
- }
-
-
- /************************************************************************
- * Convert a normal asciiz string to MSDOS/CPM FCB format. *
- * Make the filename portion 8 characters, extention 3 maximum. *
- * Expand *'s into ?'s. *
- * NOTE: doesn't end outname[] with \0, doesn't strip drive descriptor *
- ************************************************************************/
-
- cvt_to_fcb(inname, outname)
- char *inname;
- char outname[];
- {
- char c;
- int i,j;
-
- for (i = 0; i <= index(inname, ":"); i++) /* do drive descriptor */
- outname[i] = inname[i]; /* if present */
- inname += i;
- outname += i;
-
- for (i = 0; i < 8; i++) /* now expand the inname */
- {
- switch (*inname)
- {
- case '\0': /* if null or */
- case '.': /* if a dot */
- outname[i] = ' '; /* pad with blanks, */
- break;
-
- case '*': /* if asterisk */
- outname[i] = '?'; /* pad with ?'s */
- break;
-
- default:
- outname[i] = toupper(*inname);
- ++inname;
- }
- }
-
- if (*inname == '*') /* handle the *.ext case */
- ++inname;
- if (*inname == '.')
- ++inname;
-
- for (; i < 11; i++) /* now expand the extension */
- {
- switch (*inname)
- {
- case '\0': /* if null or */
- outname[i] = ' '; /* pad with blanks, */
- break;
-
- case '*': /* if asterisk */
- outname[i] = '?'; /* pad with ?'s */
- break;
-
- case '.': /* if a dot, */
- error("(cvt_to_fcb) invalid name"); /* error out */
- break;
-
- default:
- outname[i] = toupper(*inname);
- ++inname;
- }
- }
- return;
- }
-